package guda.house.web.action.front.wx;

import guda.house.biz.config.WeixinConfig;
import guda.house.biz.helper.weixin.WeixinHelper;
import guda.house.biz.helper.weixin.WeixinResponseToken;
import guda.house.biz.helper.weixin.form.CheckTokenResponse;
import guda.house.biz.helper.weixin.form.RefreshTokenResponse;
import guda.house.biz.helper.weixin.form.UserInfoResponse;
import guda.house.biz.security.AuthUser;
import guda.house.dal.dao.WxAccessDAO;
import guda.house.dal.dataobject.WxAccessDO;
import guda.house.web.security.DefaultAuth;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Calendar;

/**
 * Created by well on 16/5/28.
 */
@Controller
@RequestMapping(value = "front/wx")
public class WxIndexAction {

    private final static Logger log = LoggerFactory.getLogger(WxIndexAction.class);

    @Autowired
    private WxAccessDAO wxAccessDAO;

    @RequestMapping(value = "index.htm", method = RequestMethod.GET)
    public void index(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
        log.info("request:" + getFullContextPath(request) + "/front/wx/response.htm");
        try {
            String redirectUrl = URLEncoder.encode(getFullContextPath(request) + "/front/wx/response.htm", "UTF-8");
            response.sendRedirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeixinConfig.appId + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping(value = "response.htm", method = RequestMethod.GET)
    public String response(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {

        String code = request.getParameter("code");
        log.info("response:code=" + code);
        WeixinResponseToken weixinResponseToken = WeixinHelper.fetchToken(code);
        log.info("fetch token:" + ReflectionToStringBuilder.toString(weixinResponseToken));
        if (weixinResponseToken == null) {
            return "front/wx/authError.vm";
        }
        WxAccessDO wxAccessByOpenId = wxAccessDAO.getWxAccessByOpenId(weixinResponseToken.getOpenid());

        if (wxAccessByOpenId == null) {
            //不存在，做OAUTH授权
            //https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
            try {
                String redirectUrl = URLEncoder.encode(getFullContextPath(request) + "/front/wx/responseAuth.htm", "UTF-8");
                response.sendRedirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeixinConfig.appId + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect");
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            //如果存在，更新TOKEN

            WxAccessDO wxAccessDO = new WxAccessDO();
            wxAccessDO.setAccessId(wxAccessByOpenId.getAccessId());
            wxAccessDO.setRefreshToken(weixinResponseToken.getRefresh_token());
            wxAccessDO.setAccessToken(weixinResponseToken.getAccess_token());
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.SECOND, weixinResponseToken.getExpires_in());
            wxAccessDO.setGmtExpire(calendar.getTime());
            wxAccessDAO.updateByIdSelective(wxAccessDO);

            AuthUser authUser = new AuthUser();
            authUser.setUserId(wxAccessByOpenId.getAccessId());
            authUser.setLoginName(wxAccessByOpenId.getWxNickName());
            authUser.setFromWeixin(true);
            authUser.setRoles(new String[]{"user"});
            AuthUser.setCurrentUser(authUser);
            request.getSession().setAttribute(DefaultAuth.sessionKey, authUser);
            return "redirect:/front/mySuite.htm";

        }

        return "front/wx/authError.vm";
    }

    @RequestMapping(value = "responseAuth.htm", method = RequestMethod.GET)
    public String responseAuth(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
        String code = request.getParameter("code");
        log.info("responseAuth:code=" + code);
        WeixinResponseToken weixinResponseToken = WeixinHelper.fetchToken(code);
        log.info("fetch token:" + ReflectionToStringBuilder.toString(weixinResponseToken));
        if (weixinResponseToken == null) {
            return "front/wx/authError.vm";
        }
        UserInfoResponse userInfoResponse = WeixinHelper.fetchUserInfo(weixinResponseToken.getAccess_token(), weixinResponseToken.getOpenid());
        log.info("fetch user:" + ReflectionToStringBuilder.toString(userInfoResponse));
        if (userInfoResponse == null) {
            return "front/wx/authError.vm";
        }
        WxAccessDO wxAccessDO = new WxAccessDO();
        wxAccessDO.setRefreshToken(weixinResponseToken.getRefresh_token());
        wxAccessDO.setAccessToken(weixinResponseToken.getAccess_token());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, weixinResponseToken.getExpires_in());
        wxAccessDO.setGmtExpire(calendar.getTime());
        wxAccessDO.setSubscribe(userInfoResponse.getSubscribe());
        wxAccessDO.setCity(userInfoResponse.getCity());
        wxAccessDO.setProvince(userInfoResponse.getProvince());
        wxAccessDO.setCountry(userInfoResponse.getCountry());
        wxAccessDO.setGroupId(userInfoResponse.getGroupid());
        wxAccessDO.setUnionid(userInfoResponse.getUnionid());
        wxAccessDO.setWxNickName(userInfoResponse.getNickname());
        wxAccessDO.setWxUserImg(userInfoResponse.getHeadimgurl());
        wxAccessDO.setWxLanguage(userInfoResponse.getLanguage());
        wxAccessDO.setWxSex(userInfoResponse.getSex());
        wxAccessDO.setOpenid(weixinResponseToken.getOpenid());
        Long insert = wxAccessDAO.insert(wxAccessDO);
        AuthUser authUser = new AuthUser();
        authUser.setUserId(insert);
        authUser.setLoginName(wxAccessDO.getWxNickName());
        authUser.setRoles(new String[]{"user"});
        authUser.setFromWeixin(true);
        AuthUser.setCurrentUser(authUser);

        request.getSession().setAttribute(DefaultAuth.sessionKey, authUser);
        return "redirect:/front/mySuite.htm";
    }

    public static String getFullContextPath(HttpServletRequest request) {
        String port = 80 == request.getServerPort() ? "" : ":" + request.getServerPort();
        return request.getScheme() + "://" + request.getServerName() + port + request.getContextPath();
    }
}
